package com.qf.controller;

import com.qf.common.R;
import com.qf.constatns.AuthConstatns;
import com.qf.constatns.CarConstants;
import com.qf.feign.api.GoodsService;
import com.qf.vo.Car;
import com.qf.vo.Customer;
import com.qf.vo.Goods;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

@Controller
@RequestMapping("/carController")
@Slf4j
public class CarController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private GoodsService goodsService;


    /**
     * 1、如果用户登录了就把购物车保存到redis中，key是就是用户的Id
     * 2、如果用户没有登录需要创建一个匿名用户Id，把商品放到redis中，还需要把匿名id写到用户
     *
     * @param car
     * @return
     */
    @PostMapping("/addCar")
    @ResponseBody
    public R addCar(Car car, HttpSession session,
                    HttpServletResponse response,
                    @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME, defaultValue = "") String anneId) {

        // 1.获取当前登录的用户
        Customer customer = (Customer) session.getAttribute(AuthConstatns.AUTH_SESSION);

        // 2.创建一个Map和reids绑定
        BoundHashOperations<String, Object, Object> userCarHash = null;

        // 3.判断用户是否为空
        if (customer != null) {
            // 已经登录了，说明有用户Id
            Integer uid = customer.getId();

            // 1.使用Map和缓存中的hash结构绑定
            userCarHash = redisTemplate.boundHashOps(CarConstants.USERCARPRE + uid);
//            userCarHash.expire(100, TimeUnit.SECONDS)
        } else {
            //   没有登录,创建一个匿名id,判断这个匿名用户名是否已经存在了匿名id
            if (StringUtils.isEmpty(anneId)) {
                // 匿名用户是第一次添加，写cookie
                anneId = UUID.randomUUID().toString();
                Cookie cookie = new Cookie(CarConstants.ANNO_CAR_COOKIE_NAME, anneId);
                cookie.setMaxAge(60 * 60 * 24 * 7); // 7天
                cookie.setPath("/"); // 跨域问题
                response.addCookie(cookie);
            }
            userCarHash = redisTemplate.boundHashOps(CarConstants.USERCARPRE + anneId);
        }
        // 2 把购物车数据放入到map中 uid gid sum
        userCarHash.put(car.getGid().toString(), car.getSum().toString());
        log.debug("{}", car);
        return R.success();
    }

    @PostMapping("/updateCar")
    @ResponseBody
    public R updateCar(String gid, String type, HttpSession session,
                       @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME, defaultValue = "") String annoId) {

        // 1.获取当前登录用户
        Customer customer = (Customer) session.getAttribute(AuthConstatns.AUTH_SESSION);

        BoundHashOperations<String, Object, Object> carMap = null;
        if (customer != null) {
            carMap = redisTemplate.boundHashOps(CarConstants.USERCARPRE + customer.getId());
        } else {
            if (!StringUtils.isEmpty(annoId)) {
                carMap = redisTemplate.boundHashOps(CarConstants.USERCARPRE + annoId);
            }
        }

        switch (type) {
            case CarConstants.CAR_INCR:
                // 自增
                carMap.increment(gid, 1);
                break;
            case CarConstants.CAR_DECR:
                Integer num = Integer.parseInt(carMap.get(gid).toString());
                carMap.put(gid, (--num) + "");
                break;
        }
        return R.success();
    }

    @GetMapping("/deleteCar")
    @ResponseBody
    public R deleteCar() {
        return R.success();
    }


    /**
     * 合并购物车
     * 1、把匿名用户的购物车查到
     * 2、添加到用户id的集合中
     *
     * @param uid
     * @param annoId
     * @return
     */
    @GetMapping("/mergeCar/{uid}/{annoId}")
    @ResponseBody
    public R mergeCar(@PathVariable Integer uid, @PathVariable String annoId) {

        // 绑定用户id购物车
        BoundHashOperations<String, Object, Object> userIdCarMap = redisTemplate.boundHashOps(CarConstants.USERCARPRE + uid);

        // 绑定匿名id购物车
        BoundHashOperations<String, Object, Object> annoIdCarMap = redisTemplate.boundHashOps(CarConstants.USERCARPRE + annoId);

        Map<Object, Object> annoCarMap = annoIdCarMap.entries();
        Set<Map.Entry<Object, Object>> entries1 = annoCarMap.entrySet();
        for (Map.Entry<Object, Object> entry : entries1) {
            Object key = entry.getKey(); // gid
            Object value = entry.getValue(); // sum

            // 判断登录的购物车中是否有这个商品
            if (userIdCarMap.hasKey(key)) {
                Integer uNum = Integer.parseInt(userIdCarMap.get(key).toString());
                Integer aNum = Integer.parseInt(value.toString());
                value = (uNum + aNum) + ""; // 相加
            }
            userIdCarMap.put(key, value);
        }

        // 清空匿名的redis
//        redisTemplate.delete(CarConstants.ANNO_CAR_COOKIE_NAME+annoId);
        redisTemplate.delete(CarConstants.USERCARPRE + annoId);

        // Cookie cookieValue = new Cookie(CarConstants.ANNO_CAR_COOKIE_NAME,"");


        return R.success();
    }

    @GetMapping("/getUserCarList")
    public String getUserCarList(HttpSession session, ModelMap modelMap, @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME, required = false, defaultValue = "") String annoId) {

        // 1.获取当前登录用户
        Customer customer = (Customer) session.getAttribute(AuthConstatns.AUTH_SESSION);


        BigDecimal totalPrice = new BigDecimal(0.0);

        BoundHashOperations<String, Object, Object> carMap = null;
        if (customer != null) {
            carMap = redisTemplate.boundHashOps(CarConstants.USERCARPRE + customer.getId());
        } else {
            if (!StringUtils.isEmpty(annoId)) {
                carMap = redisTemplate.boundHashOps(CarConstants.USERCARPRE + annoId);
            }
        }
        List<Car> carList = new ArrayList<>();
        if (carMap != null) {
            Map<Object, Object> mapEntries = carMap.entries();
            for (Map.Entry<Object, Object> entry : mapEntries.entrySet()) {
                Object key = entry.getKey();
                Object value = entry.getValue();

                // 封装Car
                Car car = new Car();
                int gid = Integer.parseInt(key.toString());
                int sum = Integer.parseInt(value.toString());
                Goods goods = goodsService.info(gid);

                car.setGid(gid);
                car.setSum(sum);
                car.setGoods(goods);

                // 计算小计=商品数量*商品价格
                BigDecimal subTotal = goods.getGprice().multiply(BigDecimal.valueOf(sum));
                car.setSubTotal(subTotal);
                carList.add(car);

                // 计算总结=每个商品的小计累加
                // 0.0 + 100
                totalPrice = totalPrice.add(subTotal);
            }

        }

        modelMap.put("carList", carList);
        modelMap.put("totalPrice", totalPrice);

        return "carList";
    }


    @RequestMapping("/getCarListByUid/{uid}")
    @ResponseBody
    public Map<String, Object> getCarListByUid(@PathVariable Integer uid) {
        Map<String, Object> map = getCarList(null, uid);
        return map;
    }


    @RequestMapping("/getCarListByUidAndGid")
    @ResponseBody
    public Map<String, Object> getCarListByUidAndGid(@RequestParam("uid") Integer uid, @RequestParam("gidArray") List<String> gidArray) {
        log.debug("uid:{}", uid);
        log.debug("gidArray:{}", gidArray);
        Map<String, Object> map = getCarList(gidArray, uid);
        log.debug("map:{}", map);
        return map;
    }


    public Map<String,Object> getCarList(List<String> gidArray,Integer uid){

        List<Car> carList = new ArrayList<>();
        BigDecimal totalPrice = new BigDecimal(0.0);

        // 1.查询购物车  // key:gid,value:sum
        BoundHashOperations<String, Object, Object> carMap = redisTemplate.boundHashOps(CarConstants.USERCARPRE + uid);

        // 2.判断用户是否勾选了
        if (gidArray != null && gidArray.size() > 0) {
            for (String gid : gidArray) {
                String sum = (String) carMap.get(gid); // 根据用户勾选了商品id获取sum
                // 封装car对象，然后添加carList中
                toCarObject(carList, gid, sum);
            }
        } else {
            Set<Map.Entry<Object, Object>> entries = carMap.entries().entrySet();
            for (Map.Entry<Object, Object> entry : entries) {
                String key = (String) entry.getKey(); // gid
                String value = (String) entry.getValue(); // sum
                toCarObject(carList, key, value);
            }
        }

        // 3.计算总结
        for (Car car : carList) {
            totalPrice = totalPrice.add(car.getSubTotal());
        }

        // 4.返回购物车和总结
        Map<String, Object> map = new HashMap<>();
        map.put("carList", carList);
        map.put("totalPrice", totalPrice);

        return map;
    }


    private void toCarObject(List<Car> carList, String key, String value) {
        // 创建对象
        Car car = new Car();

        // 类型转换
        int gid = Integer.parseInt(key);
        int sum = Integer.parseInt(value);

        // 3.查询商品的信息
        Goods goods = goodsService.info(gid);

        // 4.封装
        car.setGid(gid);
        car.setSum(sum);
        car.setGoods(goods);

        // 5.计算小计
        BigDecimal subTotal = goods.getGprice().multiply(BigDecimal.valueOf(sum));
        car.setSubTotal(subTotal);

        carList.add(car);
    }

}
